package com.lyh.qrcode.controller;

import com.lyh.qrcode.util.ZipUtil;
import com.lyh.qrcode.util.ZxingUtils;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;

@RestController
@RequestMapping("/number")
public class NumberController {

    private static final String FILE_PATH = System.getProperty("java.io.tmpdir");
    private static final Integer NO_CELL_INDEX = 1;

    @GetMapping
    public String index() {
        return "<!DOCTYPE html>\n" +
                "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:th=\"http://www.thymeleaf.org\" xmlns:sec=\"http://www.thymeleaf.org/thymeleaf-extras-springsecurity3\">\n" +
                "<head>\n" +
                "<meta charset=\"UTF-8\" />\n" +
                "<title>工号二维码生成</title>\n" +
                "</head>\n" +
                "<body><div style='margin:0 auto;width:600px;'>" +
                "    <form action=\"#\" method=\"post\" enctype=\"multipart/form-data\">\n" +
                "    <div style='text-align:center;'><img width='100px' height='100px' src=''/>"+
                "    <h1>工号二维码生成</h1></div>\n" +
                "        <p>选择文件: <input type=\"file\" name=\"fileName\"/></p>\n" +
                "        <p>1、请上传正确格式的工号数据，即第二列为工号信息，文件后缀为.xlsx。</p>\n" +
                "        <p>2、如果数据量大，会有一定的等待时间，成功后，会自动下载打包后的文件。</p>\n" +
                "        <p>3、生成成功后，请检查导入数量与生成的图片数量是否一致。</p>\n" +
                "        <p style='text-align:center;'><input type=\"submit\" style='width:140px;height:40px;font-size:19px;' value=\"提交并下载\"/></p>\n" +
                "    </form>\n" +
                "</div></body>\n" +
                "</html>";
    }

    @PostMapping
    public ResponseEntity upload(@RequestParam("fileName") MultipartFile file) {
        String name = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYYMMddHHmmss"));
        read(file, name);
        gren(name);
        clear(name);
        HttpHeaders headers = new HttpHeaders();
        String fileName = FILE_PATH + "\\" + name + ".zip";
        File zip = new File(fileName);
        if (zip.exists()) {
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            try {
                headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
                return new ResponseEntity(FileUtils.readFileToByteArray(zip),
                        headers, HttpStatus.CREATED);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (!zip.delete()) {
                    System.out.println("清理文件失败！");
                }
            }
        }
        return ResponseEntity.ok().contentType(new MediaType("text", "html", StandardCharsets.UTF_8)).body("生成出错！");
    }

    private void clear(String name) {
        File file = new File(FILE_PATH + "\\" + name);
        if (file.exists()) {
            Arrays.stream(Objects.requireNonNull(file.listFiles())).forEach(f -> {
                if (f.exists()) {
                    if (!f.delete()) {
                        System.out.println("删除" + f.getName() + "文件失败！");
                    }
                }
            });
            if (!file.delete()) {
                System.out.println(file.getName() + "删除失败！");
            }
        }
    }

    private void gren(String name) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(new File(FILE_PATH + "\\" + name + ".zip"));
            ZipUtil.toZip(FILE_PATH + "\\" + name, outputStream, true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private void create(String name, String no) {
        FileOutputStream outputStream = null;
        try {
            BufferedImage QRcode = ZxingUtils.createQRImage(no, 800, 800, 0);
            File file = new File(FILE_PATH + "\\" + name);
            if (!file.exists() && !file.mkdirs()) {
                throw new RuntimeException("创建文件夹失败！");
            }
            outputStream = new FileOutputStream(new File(FILE_PATH + "\\" + name + "\\" + no + ".jpg"));
            ImageIO.write(QRcode, "jpg", outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void read(MultipartFile file, String name) {
        // 定义一个数据格式化对象
        XSSFWorkbook wb = null;
        InputStream in = null;
        try {
            //excel模板路径
            in = file.getInputStream();
            //读取excel模板
            wb = new XSSFWorkbook(in);

            //获取sheet表格，及读取单元格内容
            XSSFSheet sheet = wb.getSheetAt(0);
            Iterator<Row> iterator = sheet.rowIterator();
            iterator.next();
            iterator.forEachRemaining(row -> {
                row.getCell(NO_CELL_INDEX).setCellType(CellType.STRING);
                String no = row.getCell(NO_CELL_INDEX).getStringCellValue();
                create(name, no);
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (wb != null) {
                try {
                    wb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}